package com.chen106106.sstest.common.redis;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisCache implements Serializable {

	private static final long serialVersionUID = 7386984326489493737L;

	private JedisPool jedisPool;

	/**
	 * @description 获取一个对象
	 * @param String
	 *            key
	 */
	public Object get(String key) {
		Jedis jedis = null;
		Object obj = null;
		try {
			jedis = jedisPool.getResource();
			if (StringUtils.equals(key, "")) {
				return null;
			}
			return byteToObject(jedis.get(key.getBytes()));

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisPool.returnResource(jedis);// 回收
		}
		return null;

	}
     
	
	/**
	 * @description 根據key 模糊匹配 key
	 * @param pattern 匹配規則
	 * @return Map<String,Object>
	 */
	 public Map<String,Object> getLikeKey(String pattern){
	     Jedis jedis = null;
		 Object obj = null;
		 try {
			 Map<String, Object> map = new HashMap<String, Object>();
			 jedis = jedisPool.getResource();
			 if(StringUtils.equals(pattern, "")){
				 return null;
			 }
			Set<String> keys = jedis.keys(pattern);
			
			for (String key : keys) {
				map.put(key, get(key));
			}
			return map;			
		 } catch (Exception e) {
			 e.printStackTrace();
		 }finally{
			 jedisPool.returnResource(jedis);// 回收
		 }
		 return null;
	 }

	/**
	 * @descrption 对 key的value做加法 如果 不存在则设置key
	 * @param String
	 *            key
	 * @param int n 操作的数字
	 * @note key对应的值必须是 int
	 */
	public long incrby(String key, int n) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			if (!StringUtils.equals("", key)) {
				return jedis.incrBy(key, n);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisPool.returnResource(jedis);// 回收
		}
		return 0L;
	}

	public void delete(String key) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			if (!StringUtils.equals("", key)) {
				jedis.del(key);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisPool.returnResource(jedis);// 回收
		}
	}

	/**
	 * @descrption 对 key的value做减法 如果 不存在则设置key
	 * @param String
	 *            key
	 * @param int n 操作的数字
	 * @note key对应的值必须是 int
	 */
	public long decrby(String key, int n) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			if (!StringUtils.equals("", key)) {
				return jedis.decrBy(key, n);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisPool.returnResource(jedis);// 回收
		}
		return 0L;
	}

	/**
	 *@description 是否存在
	 *@param String
	 *            key
	 */
	public boolean exist(String key) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			if (StringUtils.equals("", key)) {
				return false;
			}
			return jedis.exists(key);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisPool.returnResource(jedis);// 回收
		}
		return false;
	}

	//list
	
	/**
	 * @description 保存 一个值到list
	 * @param String key
	 * @param String value
	 * @return list size
	 */
	public Long lpush(String key,String value){
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			if(StringUtils.equals("", key)){
				return 0L;
			}
			return jedis.lpush(key, value);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			jedisPool.returnResource(jedis);
		}
		return 0L;
	}
	
	/**
	 * @description 保存一个 维持n个元素的队列
	 * @param String key
	 * @param String value
	 * @param int n
	 */
	public List<String> lpushSub(String key,String value,int n){
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			if(StringUtils.equals("", key)){
				return null;
			}
			jedis.lpush(key, value);
			return jedis.lrange(key, 0, n-1);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			jedisPool.returnResource(jedis);
		}
		return null;
	}
	
	/**
	 * @description 保存一个有生存时间对象
	 * @param String
	 *            key
	 * @param int second 过期时间（分钟）0表示永不过期
	 * @param Object
	 *            object 对象
	 */
	public void set(String key, Object obj, int second) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			if (!StringUtils.equals("", key)) {
				jedis.set(key.getBytes(), objectToBytes(obj));
				if (second != 0) {
					jedis.expire(key, second * 60);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisPool.returnResource(jedis);// 回收
		}
	}
	
	/**
	 * @description 订阅
	 * @param jedisPubSub
	 * @param patterns
	 */
	public void psubscribe(MyListener jedisPubSub,String... patterns){
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.psubscribe(jedisPubSub, patterns);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisPool.returnResource(jedis);// 回收
		}
	}
	

	/**
	 * @description  发布消息
	 * @param channel
	 * @param message
	 */
	public void publish(String channel,String message){
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.publish(channel, message);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			jedisPool.returnResource(jedis);// 回收
		}
	}

	/**
	 * @description 字节转化为对象
	 * @param bytes
	 * @return
	 */
	private Object byteToObject(byte[] bytes) {
		if (bytes == null || bytes.length == 0)
			return null;
		try {
			ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
			Object obj = inputStream.readObject();
			return (Object) obj;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * @description 对象转字节
	 * @param bytes
	 * @return
	 */
	private byte[] objectToBytes(Object value) {
		if (value == null) {
			return null;
		}
		ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
		ObjectOutputStream outputStream;
		try {
			outputStream = new ObjectOutputStream(arrayOutputStream);
			outputStream.writeObject(value);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				arrayOutputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return arrayOutputStream.toByteArray();
	}
	
	
	

	public void setJedisPool(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}

}
